﻿using System;
using CuteSprite.Eme.Data.Sprite;
using HmFramework;
using HmFramework.Log;
using HmFramework.Data;
using System.ComponentModel;
using HmFramework.Data.Configuration;

namespace CuteSprite.Eme.Data.BsdUserCenter
{
	#region -- 外部用户 --

	/// <summary>外部用户</summary>
	[ModelCheckMode(ModelCheckModes.CheckTableWhenFirstUse)]
	public class BsdTemporaryUser : TemporaryUser<BsdTemporaryUser, BsdAdministrator> { }

	#endregion

	#region -- 客户联系人 --

	/// <summary>客户联系人</summary>
	[ModelCheckMode(ModelCheckModes.CheckTableWhenFirstUse)]
	public class BsdCustomerContact : CustomerContact<BsdCustomerContact, BsdCustomer> { }

	#endregion

	#region -- 部门 --

	/// <summary>组织</summary>
	[Serializable]
	[ModelCheckMode(ModelCheckModes.CheckTableWhenFirstUse)]
	public class BsdOrganize : Organize<BsdOrganize, BsdAdministrator, AdministratorOrganize, BsdStaff, StaffOrganize, BsdCustomer, PermissionScope>
	{
		#region - 附加属性 -

		private SByte _SettlementDiscount;
		/// <summary>结算折扣</summary>
		[DisplayName("结算折扣")]
		[Description("结算折扣")]
		[DataObjectField(false, false, true, 3)]
		[BindColumn(69, "SettlementDiscount", "结算折扣", null, "tinyint", 3, 0, false)]
		public virtual SByte SettlementDiscount
		{
			get { return _SettlementDiscount; }
			set { if (OnPropertyChanging(___.SettlementDiscount, value)) { _SettlementDiscount = value; OnPropertyChanged(___.SettlementDiscount); } }
		}
		#endregion

		#region - 获取/设置 字段值 -

		/// <summary>
		/// 获取/设置 字段值。
		/// 一个索引，基类使用反射实现。
		/// 派生实体类可重写该索引，以避免反射带来的性能损耗
		/// </summary>
		/// <param name="name">字段名</param>
		/// <returns></returns>
		public override Object this[String name]
		{
			get
			{
				switch (name)
				{
					case ____.SettlementDiscount: return _SettlementDiscount;
					default: return base[name];
				}
			}
			set
			{
				switch (name)
				{
					case ____.SettlementDiscount: _SettlementDiscount = Convert.ToSByte(value); break;
					default: base[name] = value; break;
				}
			}
		}
		#endregion

		#region - 字段名 -

		/// <summary>取得客户字段信息的快捷方式</summary>
		public partial class ___ : _
		{
			///<summary>结算折扣</summary>
			public static readonly Field SettlementDiscount = FindByName(____.SettlementDiscount);
			private static Field FindByName(String name)
			{
				return Meta.Table.FindByName(name);
			}
		}

		/// <summary>取得客户字段名称的快捷方式</summary>
		public partial class ____ : __
		{
			///<summary>结算折扣</summary>
			public const String SettlementDiscount = "SettlementDiscount";
		}

		#endregion 字段名

		#region - 部门数据迁移 -

		/// <summary>部门数据迁移，遍历所有实体模型中与部门实体相关联的字段</summary>
		/// <param name="srcID">源部门ID</param>
		/// <param name="destID">迁移后部门ID</param>
		public static void Transform(Int32 srcID, Int32 destID)
		{
			var models = DataModel.FindAll();
			if (null == models) { return; }

			// 遍历数据模型
			foreach (var model in models)
			{
				var tables = model.ModelTables;
				// 实体模型列表为空，跳过
				if (null == tables || tables.Count < 1)
				{
					HmTrace.WriteInfo("数据模型'{0}' 没有设置实体模型", model.DisplayName);
					continue;
				}

				// 遍历当前数据模型下所有实体模型
				foreach (var table in tables)
				{
					var columns = table.ModelColumns;
					if (null == columns || columns.Count < 1)
					{
						HmTrace.WriteInfo("数据模型'{0}'中的实体模型'{1}' 没有设置字段", model.DisplayName, table.DisplayName);
						continue;
					}

					// 查找所有绑定部门表的引用字段
					var organizeCols = columns.FindAll(c => c.Control == ControlTypes.单选引用 &&
																									c.BindModel == EntityHelper.ModelUserCenter &&
																									c.BindTable == EntityHelper.UserCenterTableOrganize &&
																									c.BindField == EntityHelper.FieldPrimaryID);
					if (null == organizeCols || organizeCols.Count < 1)
					{
						HmTrace.WriteInfo("数据模型'{0}'中的实体模型'{1}' 没有字段绑定部门表", model.DisplayName, table.DisplayName);
						continue;
					}

					var eop = CreateOperate(model, table);
					if (null == eop) { break; }
					var count = eop.Count;
					if (count < 1) { break; }

					HmTrace.WriteInfo("数据模型'{0}'中的实体模型'{1}' 共 {2} 条记录，开始迁移......", model.DisplayName, table.DisplayName, count);
					eop.BeginTransaction();
					try
					{
						var total = 0;
						var index = 0;
						var batchSize = 1000;
						while (true)
						{
							var size = Math.Min(batchSize, count - index);
							if (size <= 0) { break; }

							var list = eop.FindAll(null, null, null, index, size);
							if ((list == null) || (list.Count < 1)) { break; }
							index += list.Count;

							foreach (var entity in list)
							{
								var ischanged = false;
								foreach (var col in organizeCols)
								{
									if (Convert.ToInt32(entity[col.Name]) == srcID)
									{
										entity.SetItem(col.Name, destID);
										ischanged = true;
									}
								}
								if (ischanged)
								{
									total++;
									entity.Save();
								}
							}
						}

						eop.Commit();
						HmTrace.WriteInfo("数据模型'{0}'中的实体模型'{1}' 共迁移了 {2} 条记录", model.DisplayName, table.DisplayName, total);
					}
					catch (Exception ex)
					{
						HmTrace.WriteException(ex, "数据模型'{0}'中的实体模型'{1}' 错误 ", model.DisplayName, table.DisplayName);
						eop.Rollback();
						throw;
					}
				}
			}
		}

		#endregion

		#region - 实体操作接口，直接复制自EmeEntityFactory，不需要修改 -

		/// <summary>创建实体操作接口</summary>
		/// <param name="model">数据模型对象</param>
		/// <param name="table">模型表对象</param>
		/// <returns></returns>
		public static IEntityOperate CreateOperate(DataModel model, ModelTable table)
		{
			ValidationHelper.ArgumentNull(model, "model");
			ValidationHelper.ArgumentNull(table, "table");

			var entityName = table.Name;
			try
			{
				//EntityOperate = CurrentModelTable.CreateOperate();
				if (model.IsStatic)
				{
					#region 管理授权模型对象容器

					if (EntityHelper.ModelUserCenter == model.Name)
					{
						switch (entityName)
						{
							case EntityHelper.UserCenterTableUser:
								return ManageProvider.Provider.AdministratorFactory;

							case EntityHelper.UserCenterTableUserRole:
								return ManageProvider.Provider.AdminstratorRoleFactory;

							case EntityHelper.UserCenterTableUserOrganize:
								return ManageProvider.Provider.AdministratorOrganizeFactory;

							case EntityHelper.UserCenterTableOrganize:
								return ManageProvider.Provider.OrganizeFactory;

							case EntityHelper.UserCenterTableRole:
								return ManageProvider.Provider.RoleFactory;

							case EntityHelper.UserCenterTableMenu:
								return ManageProvider.Provider.MenuFactory;

							case EntityHelper.UserCenterTablePermissionItem:
								return ManageProvider.Provider.PermissionItemFactory;

							case EntityHelper.UserCenterTablePosition:
								return ManageProvider.Provider.PositionFactory;

							case EntityHelper.UserCenterTableStaff:
								return ManageProvider.Provider.StaffFactory;

							case EntityHelper.UserCenterTableStaffOrganize:
								return ManageProvider.Provider.StaffOrganizeFactory;

							case EntityHelper.UserCenterTableTemporaryUser:
								return ManageProvider.Provider.TemporaryUserFactory;

							case EntityHelper.UserCenterTablePermission:
								return ManageProvider.Provider.PermissionFactory;

							case EntityHelper.UserCenterTablePermissionModelView:
								return ManageProvider.Provider.PermissionModelViewFactory;

							case EntityHelper.UserCenterTablePermissionScope:
								return ManageProvider.Provider.PermissionScopeFactory;

							case EntityHelper.UserCenterTableCustomer:
								return ManageProvider.Provider.CustomerFactory;

							case EntityHelper.UserCenterTableCustomerContact:
								return ManageProvider.Provider.CustomerContactFactory;

							//case EntityHelper.UserCenterTableLog:
							//	return ManageProvider.Provider.CustomerContactFactory;

							default:
								break;
						}
					}

					#endregion

					// 静态。有实体类。加上命名空间
					var name = model.NameSpace;
					if (!name.IsNullOrWhiteSpace() && !name.EndsWith(".")) { name += "."; }
					name += entityName;
					return EntityFactory.CreateOperate(name);
				}
				else
				{
					var tableName = table.TableName;
					if (!tableName.IsNullOrWhiteSpace()) { entityName = tableName; }

					// 动态。没有实体类，动态创建
					var eop = model.CreateOperate(entityName);
					if (eop == null) { throw new HmExceptionBase("无法创建表单数据库，请检查表单设置和字段设置！"); }
					return eop;
				}
			}
			catch (Exception ex)
			{
				HmTrace.WriteException(ex);
				return null;
			}
		}

		#endregion
	}

	#endregion

	#region -- 员工 --

	/// <summary>员工</summary>
	[ModelCheckMode(ModelCheckModes.CheckTableWhenFirstUse)]
	public class BsdStaff : Staff<BsdStaff, BsdAdministrator, BsdOrganize, BsdPosition, StaffOrganize, BsdCustomer>
	{
		#region - 员工数据迁移 -

		/// <summary>
		/// 
		/// </summary>
		/// <param name="srcID"></param>
		/// <param name="destID"></param>
		public static void Transform(Int32 srcID, Int32 destID)
		{
		}

		#endregion
	}

	#endregion

	#region -- 职务 --

	/// <summary>职务</summary>
	[ModelCheckMode(ModelCheckModes.CheckTableWhenFirstUse)]
	public class BsdPosition : Position<BsdPosition, BsdStaff> { }

	#endregion

	#region -- 角色 --

	/// <summary>角色</summary>
	[ModelCheckMode(ModelCheckModes.CheckTableWhenFirstUse)]
	public class BsdRole : Role<BsdRole, BsdAdministrator, AdministratorRole, BsdOrganize, Menu, PermissionItem, PermissionScope, Permission, PermissionModelView> { }

	#endregion

	#region -- 日志 --

	/// <summary>用户访问日志</summary>
	[ModelCheckMode(ModelCheckModes.CheckTableWhenFirstUse)]
	public class BsdUserAccessLog : UserAccessLog<BsdUserAccessLog> { }

	/// <summary>用户操作日志</summary>
	[ModelCheckMode(ModelCheckModes.CheckTableWhenFirstUse)]
	public class BsdUserActionLog : UserActionLog<BsdUserActionLog, BsdRecordTracesLog> { }

	/// <summary>记录痕迹日志</summary>
	[ModelCheckMode(ModelCheckModes.CheckTableWhenFirstUse)]
	public class BsdRecordTracesLog : RecordTracesLog<BsdRecordTracesLog, BsdUserActionLog> { }

	#endregion

	#region -- 管理员 --

	/// <summary>管理员</summary>
	[Serializable]
	[ModelCheckMode(ModelCheckModes.CheckTableWhenFirstUse)]
	public class BsdAdministrator : Administrator<BsdAdministrator, BsdRole, AdministratorRole, BsdOrganize, AdministratorOrganize, AdministratorGrant,
		BsdStaff, StaffOrganize, BsdPosition, BsdCustomer, BsdCustomerContact, BsdTemporaryUser,
		Menu, PermissionItem, PermissionScope, Permission, PermissionModelView,
		BsdUserAccessLog, BsdUserActionLog, BsdRecordTracesLog> { }

	#endregion

	/// <summary>百顺达管理授权模型管理</summary>
	public class BsdManageProvider : ManageProvider<BsdAdministrator> { }
}
